import string, random

from rest_framework import serializers
from rest_framework_jwt.settings import api_settings
from rest_framework_jwt.serializers import JSONWebTokenSerializer
from django.db import transaction
from django.contrib.auth import get_user_model, authenticate

from .models import Member
from apps.system.models import VCode, Log

User = get_user_model()
jwt_payload_hander = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


class MemberMobileSignSerializer(serializers.Serializer):

    def validate(self, attrs):
        mobile = self.initial_data.get('mobile')
        vcode = self.initial_data.get('vcode')

        if mobile and vcode:
            # 验证码验证
            vc = VCode.verify(mobile, vcode, VCode.SIGN)
            user = User.objects.filter(username=mobile).first()

            if not user:
                """注册"""
                name = ''.join(random.sample(string.ascii_letters + string.digits, 5))

                with transaction.atomic():
                    user = User.objects.create_user(username=mobile, name=name, type=User.MEMBER)
                    Member.objects.create(user=user)
                    vc.is_used = True
                    vc.save()

            if not user.is_active:
                raise serializers.ValidationError("该账户已禁用！")

            payload = jwt_payload_hander(user)

            return {
                'token': jwt_encode_handler(payload),
                'user_id': user.id,
                'username': user.name
            }
        else:
            msg = '参数无效'
            raise serializers.ValidationError(msg)


class MemberLoginByPwdSerializer(JSONWebTokenSerializer):
    def validate(self, attrs):
        credentials = {
            self.username_field: attrs.get(self.username_field),
            'password': attrs.get('password')
        }
        # all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE
        if all(credentials):
            user = authenticate(**credentials)
            if user and user.is_active:
                payload = jwt_payload_hander(user)
                Log.objects.addLog(user, Log.INSERT, '会员[%s]密码登录！')
                return {
                    'token': jwt_encode_handler(payload),
                    'username': user.username
                }
        raise serializers.ValidationError('账号密码错误！')


class MemberSerializer(serializers.ModelSerializer):
    class Meta:
        model = Member
        fields = '__all__'


class MemberObtainSerializer(serializers.ModelSerializer):
    name = serializers.CharField(read_only=True, source='user.name')
    gender = serializers.IntegerField(read_only=True, source='user.gender')

    class Meta:
        model = Member
        fields = '__all__'
